using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using ProjectEuler.Core.Helpers;

namespace ProjectEuler.Core
{
    public class Problem35 : IProjectEulerProblem
    {
        protected IList<string> GetAllRotations(int number)
        {
            var list = new List<string>();
            var num = number.ToString();
            while (list.Count < num.Length)
            {
                list.Add(num);
                num = Rotate(num);
            }
            return list;
        }

        private static string Rotate(string number)
        {
            var sb = new StringBuilder(number);
            sb.Append(sb[0]);
            sb.Remove(0, 1);
            return sb.ToString();
        }

        protected IList<int> AllCircularPrimesUnder(int number)
        {
            var list = new List<int>();
            for (int i = 2; i < number; i++)
            {
                var rotations = GetAllRotations(i);
                if (rotations.All(rotation => MathHelper.IsPrime(int.Parse(rotation))))
                {
                    list.Add(i);
                }
            }
            return list;
        }

        public int Number
        {
            get { return 35; }
        }

        public string Description
        {
            get { return "How many circular primes are there below one million?"; }
        }

        public string Answer
        {
            get { return AllCircularPrimesUnder(1000000).Count.ToString(); }
        }
    }

    [TestFixture]
    public class Problem35Tests : Problem35
    {
        [Test]
        public void Can_get_all_rotations_of_a_number()
        {
            var rotations = GetAllRotations(197);

            Assert.IsTrue(rotations.Contains("197"));
            Assert.IsTrue(rotations.Contains("971"));
            Assert.IsTrue(rotations.Contains("719"));
            Assert.AreEqual(3, rotations.Count);
        }

        [Test]
        public void There_are_13_circular_primes_below_100()
        {
            var circprimes = AllCircularPrimesUnder(100);
            Assert.AreEqual(13, circprimes.Count);
        }
    }
}